import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

typedef WidgetCallbackNull = Widget? Function();
typedef WidgetContextCallback = Widget Function(BuildContext);

//根据条件是否显示组件 不显示就会使用SizedBox.shrink()，
class ObxShrink extends ObxWidget {
  final WidgetCallback builder;
  final ValueGetter<bool> condition;

  const ObxShrink(this.condition, this.builder, {super.key});

  @override
  Widget build() => condition() ? builder() : SizedBox.shrink();
}

// 实现PreferredSizeWidget
class ObxSize extends ObxWidget implements PreferredSizeWidget {
  final WidgetCallback builder;
  @override
  final Size preferredSize;

  const ObxSize(this.builder, this.preferredSize, {super.key});

  @override
  Widget build() => builder();
}

// 实现PreferredSizeWidget
class ObxBuilderSize extends ObxBuilderWidget implements PreferredSizeWidget {
  final WidgetContextCallback builder;
  @override
  final Size preferredSize;

  const ObxBuilderSize(this.builder, this.preferredSize, {super.key});

  @override
  Widget build(context) => builder(context);
}

//回调BuildContext，
class ObxBuilder extends ObxBuilderWidget {
  final WidgetContextCallback builder;

  const ObxBuilder(this.builder, {Key? key}) : super(key: key);

  @override
  Widget build(context) => builder(context);
}

//回调BuildContext，
abstract class ObxBuilderWidget extends StatefulWidget {
  const ObxBuilderWidget({Key? key}) : super(key: key);

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(ObjectFlagProperty<Function>.has('builder', build));
  }

  @override
  ObxBuilderState createState() => ObxBuilderState();

  @protected
  Widget build(BuildContext context);
}

//回调BuildContext，
class ObxBuilderState extends State<ObxBuilderWidget> {
  final _observer = RxNotifier();
  late StreamSubscription subs;

  @override
  void initState() {
    super.initState();
    subs = _observer.listen(_updateTree, cancelOnError: false);
  }

  void _updateTree(_) {
    if (mounted) {
      setState(() {});
    }
  }

  @override
  void dispose() {
    subs.cancel();
    _observer.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => RxInterface.notifyChildren(_observer, () => widget.build(context));
}
